package layer
{
	import map.data.BirthPoint;
	import map.data.Obstacle;
	import map.data.RadCell;
	
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import map.geometry.RadLine;
	
	import radevent.RadGameEvent;
	
	import view.RadCellView;

	public class CellLayer extends BaseLayer
	{
		public static const X_STEP:int = 100;
		public static const Y_STEP:int = 50;
		private var _topPoints:Array;
		private var _bottomPoints:Array;
		private var _leftPoints:Array;
		private var _rightPoints:Array;
		private var _rampUnderLines:Vector.<RadLine>;
		private var _rampTopLines:Vector.<RadLine>;
		private var _cells:Vector.<RadCellView>;
		private var _mouseDown:Boolean = false;
		private var _mouseRightDown:Boolean = false;
		
		private var _obstacle:Shape;
		private var _line:Shape;
		
		private var _startPoint:Point;
		private var _endPoint:Point;
		public function CellLayer()
		{
			super();
			this.addEventListener(Event.ADDED_TO_STAGE,onAddToStage);
			_obstacle = new Shape();
			_line = new Shape();
			_line.graphics.lineStyle(1,0xff0000);
			addChild(_line);
			addChild(_obstacle);
		}
		
		private function onAddToStage(event:Event):void
		{
			this.stage.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
			this.stage.addEventListener(MouseEvent.RIGHT_MOUSE_UP,onRightMouseUp);
		}
		
		private function onMouseDown(event:MouseEvent):void
		{
			_mouseDown = true;
			_mouseRightDown = false;
			if(_optionType == MapEditor.BRUSH)
			{
				dispatchEvent(new RadGameEvent(RadGameEvent.ADD_WALK_CELL,event.currentTarget.clone()));
			}else if(_optionType == MapEditor.OBSTACLE)
			{
				var cell:RadCellView = event.currentTarget as RadCellView;
				var p:Point = cell.getCloseInPoint(new Point(event.localX,event.localY));
				_startPoint = p;
				_obstacle.graphics.clear();
				_obstacle.graphics.beginFill(0xffffff);
				_obstacle.graphics.drawCircle(p.x,p.y,5);
				_obstacle.graphics.endFill();
				_obstacle.graphics.moveTo(p.x,p.y);
//				dispatchEvent(new RadGameEvent(RadGameEvent.ADD_WALK_CELL,event.currentTarget));
			}else if(_optionType == MapEditor.BIRTH_POINT)
			{
				dispatchEvent(new RadGameEvent(RadGameEvent.ADD_BIRTHPOINT,new BirthPoint(event.currentTarget.center.x,event.currentTarget.center.y)));
			}
		}
		
		private function onRightMouseDown(event:MouseEvent):void
		{
			_mouseRightDown = true;
			_mouseDown = false;
			if(_optionType == MapEditor.BRUSH)
			{
				dispatchEvent(new RadGameEvent(RadGameEvent.REMOVE_WALK_CELL,event.currentTarget));
			}else if(_optionType == MapEditor.OBSTACLE)
			{
				//				dispatchEvent(new RadGameEvent(RadGameEvent.ADD_WALK_CELL,event.currentTarget));
			}
		}
		
		private function onRightMouseUp(event:MouseEvent):void
		{
			_mouseRightDown = false;
		}
		
		private function onMouseUp(event:MouseEvent):void
		{
			_mouseDown = false;
			if(_optionType == MapEditor.OBSTACLE)
			{
				if(_startPoint && _endPoint && Point.distance(_startPoint,_endPoint)>1)
				{
					dispatchEvent(new RadGameEvent(RadGameEvent.ADD_OBSTACLE,new Obstacle(new RadLine(_startPoint,_endPoint))));
					_startPoint = _endPoint = null;
				}
				_obstacle.graphics.clear();
			}
		}
		
		public function draw(target:DisplayObject):void
		{
			_topPoints = [];
			_bottomPoints = [];
			_leftPoints = [];
			_rightPoints = [];
			_rampUnderLines = new Vector.<RadLine>();
			_rampTopLines = new Vector.<RadLine>();
			_cells = new Vector.<RadCellView>();
			var w:Number = Math.ceil(target.width/X_STEP)*X_STEP;
			var h:Number = Math.ceil(target.height/Y_STEP)*Y_STEP;
			
			this.graphics.clear();
			this.graphics.beginFill(0xff0000,0);
			this.graphics.drawRect(0,0,w,h);
			this.graphics.endFill();
			
			var i:int=0;
			while(i<=w){
				var p1:Point = new Point(i,0);
				var p2:Point = new Point(i,h);
				_topPoints.push(p1);
				_bottomPoints.push(p2);
				i+=X_STEP;
			}
			i=0
			while(i<=h){
				var p3:Point = new Point(0,i);
				var p4:Point = new Point(w,i);
				_leftPoints.push(p3);
				_rightPoints.push(p4);
				i+=Y_STEP;
			}
			var top_right:Array;
			var left_botttom:Array;
			var top_left:Array;
			var right_bottom:Array;
			
			var copy_top:Array = _topPoints.concat();
			copy_top.pop();
			top_right = copy_top.concat(_rightPoints);
			var copy_left:Array = _leftPoints.concat();
			copy_left.pop();
			left_botttom = copy_left.concat(_bottomPoints);
			copy_top = _topPoints.concat().reverse();
			copy_top.pop();
			top_left = copy_top.concat(_leftPoints);
			var copy_right:Array = _rightPoints.concat();
			copy_right.pop();
			right_bottom = copy_right.concat(_bottomPoints.reverse());
			
			for(i=1;i<top_right.length-1;i++){
				var line1:RadLine = new RadLine(top_right[i],left_botttom[i]);
				var line2:RadLine = new RadLine(top_left[i],right_bottom[i]);
				drawLine(line1);
				drawLine(line2);
				_rampTopLines.push(line1);
				_rampUnderLines.push(line2);
			}
			for(i=0;i<_rampTopLines.length-1;i++)
			{
				for(var j:int=0;j<_rampUnderLines.length-1;j++)
				{
					if(_rampTopLines[i].intersect(_rampUnderLines[j]) && _rampTopLines[i].intersect(_rampUnderLines[j+1])
						&& _rampTopLines[i+1].intersect(_rampUnderLines[j]) && _rampTopLines[i+1].intersect(_rampUnderLines[j+1]))
					{
						var _line1:RadLine = _rampTopLines[i];
						var _line2:RadLine = _rampTopLines[i+1];
						var _line3:RadLine = _rampUnderLines[j];
						var _line4:RadLine = _rampUnderLines[j+1];
						var _point1:Point = _line1.intersectPoint(_line3);
						var _point2:Point = _line1.intersectPoint(_line4);
						var _point3:Point = _line2.intersectPoint(_line3);
						var _point4:Point = _line2.intersectPoint(_line4);
						var cell:RadCellView = new RadCellView(new RadCell(_point1,_point2,_point3,_point4));
						addChild(cell);
						cell.addEventListener(MouseEvent.MOUSE_OVER,onCellOver);
						cell.addEventListener(MouseEvent.MOUSE_MOVE,onCellMove);
						cell.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
						cell.addEventListener(MouseEvent.RIGHT_MOUSE_DOWN,onRightMouseDown);
					}
				}
			}
//			drawInsecect();
		}
		
		private function drawLine(line:RadLine):void
		{
			_line.graphics.moveTo(line.p1.x,line.p1.y);
			_line.graphics.lineTo(line.p2.x,line.p2.y);
		}
		
		private function onCellOver(event:MouseEvent):void
		{
			if(_optionType == MapEditor.BRUSH){
				if(_mouseDown)
				{
					dispatchEvent(new RadGameEvent(RadGameEvent.ADD_WALK_CELL,event.currentTarget.clone()));
				}else if(_mouseRightDown)
				{
					dispatchEvent(new RadGameEvent(RadGameEvent.REMOVE_WALK_CELL,event.currentTarget));
				}
			}
		}
		
		private function onCellMove(event:MouseEvent):void
		{
			if(_optionType == MapEditor.OBSTACLE){
				if(_mouseDown)
				{
					var p:Point = new Point(event.localX,event.localY);
					var cell:RadCellView = event.currentTarget as RadCellView;
					p = cell.getCloseInPoint(p);
					_obstacle.graphics.clear();
					_obstacle.graphics.beginFill(0xffffff);
					_obstacle.graphics.lineStyle(2,0xffffff);
					_obstacle.graphics.drawCircle(_startPoint.x,_startPoint.y,5);
					_obstacle.graphics.moveTo(_startPoint.x,_startPoint.y);
					_obstacle.graphics.lineTo(p.x,p.y);
					_obstacle.graphics.drawCircle(p.x,p.y,5);
					_obstacle.graphics.endFill();
					_endPoint = p;
				}else if(_mouseRightDown)
				{
//					dispatchEvent(new RadGameEvent(RadGameEvent.REMOVE_WALK_CELL,event.currentTarget));
				}
			}
		}
		
		/**
		 * for test 
		 * 
		 */		
		private function drawInsecect():void{
			this.graphics.beginFill(0xff0000,1);
			for(var i:int=0;i<_rampTopLines.length;i++)
			{
				for(var j:int=0;j<_rampUnderLines.length;j++)
				{
					if(_rampTopLines[i].intersect(_rampUnderLines[j]))
					{
						var point:Point = _rampTopLines[i].intersectPoint(_rampUnderLines[j]);
						this.graphics.drawCircle(point.x,point.y,10);
					}
				}
			}
			this.graphics.endFill();
		}
	}
}